package com.paw.security.jwt.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.paw.security.jwt.domain.Result;
import com.paw.security.jwt.util.JwtTokenUtil;
import com.paw.security.jwt.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: TokenLoginFilter
 * @Description: 认证的 filter
 * @Author oyc
 * @Date 2020/12/29 10:09
 * @Version 1.0
 */
@Slf4j
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
  private AuthenticationManager authenticationManager;
//  private TokenManager tokenManager;

  public TokenLoginFilter(AuthenticationManager authenticationManager) {
    this.authenticationManager = authenticationManager;
//    this.tokenManager = tokenManager;
    this.setPostOnly(false);
    this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException {
    try {
      // from 方式提交
      Map<String, String[]> map = req.getParameterMap();
      String username = map.get("username")[0];
      String password = map.get("password")[0];
      User user = new User(username, password, new ArrayList<>());
      // json 方式提交
//      User user1 = new ObjectMapper().readValue(req.getInputStream(), User.class);
      UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList<>());
      return authenticationManager.authenticate(authenticationToken);
    } catch (Exception e) {
      log.error("TokenLoginFilter attemptAuthentication error. ",e);
      throw new RuntimeException(e);
    }
  }

  /**
   * 登录成功
   */
  @Override
  protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) throws IOException, ServletException {
    User user = (User)auth.getPrincipal();
    String token = JwtTokenUtil.createToken(user.getUsername());
    HashMap<Object, Object> map = new HashMap<>();
    map.put("token",token);
    map.put("user",user);
    map.put("loginName",user.getUsername());
    ResponseUtil.out(response, Result.ok(map));
  }

  /**
   * 登录失败
   */
  @Override
  protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
    ResponseUtil.out(response, Result.error("登录失败"));
  }
}